#include "Common/AttrMgr/AttrMgr.h"
#include "Common/TableData/AttributeConvertCfg.h"

#define Advance_begin 100001
#define Advance_end 100024
#define advance_round  6


/*#define MgrInit(name, logstr) { \
//if (!g_Make##name##())   \
//	{\
//	LogErrPrint("MakeInstance Mgr error, name: "#logstr); \
//	return false; \
//	}\
//if (!g_Get##name##()->Init())\
//	{\
//	LogErrPrint("Init Mgr error, name: "#logstr); \
//	return false; \
//	}\
}*/

/*#define MgrUnit(name) {\
//	g_Get##name##()->Unit(); \
//	g_Del##name##(); \
}*/

AttrMgr::AttrMgr()
{
	memset(m_CAttrToPAttr, P_NONE, sizeof(uint32_t)*C_MAX);
	memset(m_PAttrBroadCast, 0, sizeof(uint32_t)*P_MAX);
	memset(m_CAttrToAdvAttr, 0, sizeof(uint32_t)*C_MAX);
	memset(m_CAttrToMAttr, 0, sizeof(uint32_t)*C_MAX);
	memset(m_MAttrBroadCast, 0, sizeof(uint32_t)*M_MAX);
	m_mapMonsterAddFormula.clear();
	m_mapMAFinalFormula.clear();
	m_mapPlayerAddFormula.clear();
	m_mapTransAttrs.clear();
	m_mapPAFinalFormula.clear();
}

AttrMgr::~AttrMgr()
{
}

bool AttrMgr::Init()
{
	bool result = false;

	InitPlayerAttr();
	InitMonsterAttr();
	InitCurrencyName();
/*
	MMOLOG_PROCESS_ERROR(g_MakeSkillMgr());
	MMOLOG_PROCESS_ERROR(g_GetSkillMgr()->Init());*/

	result = true;
//Exit0:
	return result;
}

bool AttrMgr::UnInit()
{
	bool result = false;

	memset(m_CAttrToPAttr, P_NONE, sizeof(uint32_t)*C_MAX);
	memset(m_PAttrBroadCast, 0, sizeof(uint32_t)*P_MAX);
	memset(m_CAttrToAdvAttr, 0, sizeof(uint32_t)*C_MAX);
	memset(m_CAttrToMAttr, 0, sizeof(uint32_t)*C_MAX);
	memset(m_MAttrBroadCast, 0, sizeof(uint32_t)*M_MAX);

	AttrVecMap::iterator formulaIter = m_mapPlayerAddFormula.begin();
	for (; formulaIter != m_mapPlayerAddFormula.end(); formulaIter++)
		formulaIter->second.clear();
	m_mapPlayerAddFormula.clear();
	m_mapMonsterAddFormula.clear();
	m_mapMAFinalFormula.clear();
	m_mapTransAttrs.clear();
	m_mapPAFinalFormula.clear();

	//MMOLOG_PROCESS_ERROR(g_GetSkillMgr()->Unit());
	result = true;
//Exit0:
	return result;

}

void AttrMgr::RegisterPAFormula(uint32_t attrType, uint32_t PANum)
{

	
	VecAttr& vAttrs = m_mapPlayerAddFormula[attrType];
	if (vAttrs.empty())
		vAttrs.push_back(attrType);
	vAttrs.push_back(PANum);
	
	
}

void AttrMgr::RegisterMAFormula(uint32_t attrType, uint32_t MANum)
{

	if (attrType == M_AP)
	{
		VecAttr& vAttrsP = m_mapMonsterAddFormulHasPercent[attrType];
		if (vAttrsP.empty())
		{
			vAttrsP.push_back(attrType);
			vAttrsP.push_back(M_APRATE);
		}
		vAttrsP.push_back(MANum);
	}
	else if (attrType == M_MAT)
	{
		VecAttr& vAttrsP = m_mapMonsterAddFormulHasPercent[attrType];
		if (vAttrsP.empty())
		{
			vAttrsP.push_back(attrType);
			vAttrsP.push_back(M_MATRATE);
		}
		vAttrsP.push_back(MANum);
	}
	else if (M_DP == attrType)
	{
		VecAttr& vAttrsP = m_mapMonsterAddFormulHasPercent[attrType];
		if (vAttrsP.empty())
		{
			vAttrsP.push_back(attrType);
			vAttrsP.push_back(M_DPRATE);
		}
		vAttrsP.push_back(MANum);
	}
	else if (M_MDP == attrType)
	{
		VecAttr& vAttrsP = m_mapMonsterAddFormulHasPercent[attrType];
		if (vAttrsP.empty())
		{
			vAttrsP.push_back(attrType);
			vAttrsP.push_back(M_MDPRATE);
		}
		vAttrsP.push_back(MANum);
	}
	else if (M_MSPEED == attrType)
	{
		VecAttr& vAttrsP = m_mapMonsterAddFormulHasPercent[attrType];
		if (vAttrsP.empty())
		{
			vAttrsP.push_back(attrType);
			vAttrsP.push_back(M_SPEED_PERCENT);
		}
		vAttrsP.push_back(MANum);
	}
	else  //不含百分比的
	{
		VecAttr& vAttrs = m_mapMonsterAddFormula[attrType];
		if (vAttrs.empty())
			vAttrs.push_back(attrType);
		vAttrs.push_back(MANum);
	}
}


void AttrMgr::HandleMAddFormula()
{
	AttrVecMap tmpVecMap;
	uint32_t i;
	//每个属性注册相应的加法
	AttrVecMap::iterator iter = m_mapMonsterAddFormula.begin();
	for (; iter != m_mapMonsterAddFormula.end(); iter++)
	{
		VecAttr& vKeyAttrs = iter->second;
		for (i = 1; i < vKeyAttrs.size(); i++)
			tmpVecMap[vKeyAttrs[i]] = vKeyAttrs;
	}
	m_mapMonsterAddFormula.clear();
	m_mapMonsterAddFormula = tmpVecMap;

	//含有百分比相加的
	AttrVecMap tmpVecMapP;
	//每个属性注册相应的加法
	AttrVecMap::iterator iterP = m_mapMonsterAddFormulHasPercent.begin();
	for (; iterP != m_mapMonsterAddFormulHasPercent.end(); iterP++)
	{
		VecAttr& vKeyAttrs = iterP->second;
		for (i = 1; i < vKeyAttrs.size(); i++)
			tmpVecMapP[vKeyAttrs[i]] = vKeyAttrs;
	}
	m_mapMonsterAddFormulHasPercent.clear();
	m_mapMonsterAddFormulHasPercent = tmpVecMapP;
}


void AttrMgr::HandlePAddFormula()
{
	AttrVecMap tmpVecMap;
	uint32_t i;
	//每个属性注册相应的加法
	AttrVecMap::iterator iter = m_mapPlayerAddFormula.begin();
	for (; iter != m_mapPlayerAddFormula.end(); iter++)
	{
		VecAttr& vKeyAttrs = iter->second;
		for (i = 0; i < vKeyAttrs.size(); i++)
			tmpVecMap[vKeyAttrs[i]] = vKeyAttrs;
	}
	m_mapPlayerAddFormula.clear();
	m_mapPlayerAddFormula = tmpVecMap;
}

void AttrMgr::InitPlayerBaseAttr()
{
	//注册公共属性与玩家属性id映射关系
	//付战斗属性
	for (int i = C_POWER; i < C_FIGHT_ATTR_END;++i)
	{
		m_CAttrToPAttr[i] = P_ATTR_ULONG_END + i;
	}

	for (int i = C_FIGHT_POWER; i < C_FIXATION_END; ++i)
	{
		m_CAttrToPAttr[i] = i;
	}

	//金币单独处理,64位，移了位置
	m_CAttrToPAttr[C_GOLD] = P_GOLD;

	//其它模块的注册
	for (int m = enFightAttrModule_Level; m < enFightAttrModule_Max; ++m)
	{
		//注册公共属性与玩家装备属性id映射关系
		for (int i = C_POWER; i < C_FIGHT_ATTR_END; ++i)
		{
			m_CAttrToPAttr[C_FIXATION_END + (m - 1)*C_FIGHT_ATTR_END + i] = P_CLIENT_END + (m - 1)*C_FIGHT_ATTR_END + i;
		}

		//注册装备属性值对应玩家属性公式中
		//******************整数属性类******************
		for (int i = C_POWER; i < C_FIGHT_ATTR_END; ++i)
		{
			RegisterPAFormula(i + P_ATTR_ULONG_END, P_CLIENT_END + (m - 1)*C_FIGHT_ATTR_END + i);
		}
	}

}

void AttrMgr::InitPlayerAdvanceAttr()
{
	m_CAttrToPAttr[C_ATTR_POINT]			  = P_ATTR_POINT;				//属性点数
	m_CAttrToPAttr[C_ATTR_POINT_POWER]        = P_ATTR_POINT_POWER;			//属性点加成力量
	m_CAttrToPAttr[C_ATTR_POINT_INTELLIGENCE] = P_ATTR_POINT_INTELLIGENCE;	//属性点加成智力
	m_CAttrToPAttr[C_ATTR_POINT_AGILITY]      = P_ATTR_POINT_AGILITY;		//属性点加成敏捷
	m_CAttrToPAttr[C_ATTR_POINT_PHYSIQUE]     = P_ATTR_POINT_PHYSIQUE;		//属性点加成体质
	m_CAttrToPAttr[C_ATTR_POINT_ENDURANCE]    = P_ATTR_POINT_ENDURANCE;		//属性点加成耐力
	m_CAttrToPAttr[C_ATTR_POINT_PRECISION]    = P_ATTR_POINT_PRECISION;		//属性点加成精准



	//注册配置表属性
	//InitAdvCfgIdTransToPAttr();

	//******************整数属性类******************

	RegisterPAFormula(P_POWER, P_ATTR_POINT_POWER);
	RegisterPAFormula(P_INTELLIGENCE, P_ATTR_POINT_INTELLIGENCE);
	RegisterPAFormula(P_AGILITY, P_ATTR_POINT_AGILITY);
	RegisterPAFormula(P_PHYSIQUE, P_ATTR_POINT_PHYSIQUE);
	RegisterPAFormula(P_ENDURANCE, P_ATTR_POINT_ENDURANCE);
	RegisterPAFormula(P_PRECISION, P_ATTR_POINT_PRECISION);
}

void AttrMgr::InitAdvCfgIdTransToPAttr()
{
	uint32_t profId = 0;
	uint32_t i = 0;
	uint32_t advAttrId = 0;
	uint32_t baseAttrId = 0;
	uint32_t baseAttrValue = 0;

	const AttributeConvertCfgMap* pAttrMap = g_GetAttributeConvertCfgTable()->GetAttributeConvertCfgMap();
	if (!pAttrMap)
	{
		LogErrFmtPrint("GetAttributeConvertCfgMap is null!");
		return;
	}

	AttributeConvertCfgMap::const_iterator iter = pAttrMap->begin();
	for (; iter != pAttrMap->end(); iter++)
	{
		profId = iter->second.professionID;
		AdvAttrMap& profmap = m_mapTransAttrs[profId];
		advAttrId = m_CAttrToPAttr[iter->second.attribute_Id];
		mapAttr&    attrmap = profmap[advAttrId];

		const VecAttributeConvertAttributeCfg& vecCfg = iter->second.vecAttributeConvertAttributeCfg;
		for (i = 0; i < vecCfg.size(); i++)
		{
			if (vecCfg[i].Type == 0)
				continue;
			baseAttrValue = vecCfg[i].Value;
			baseAttrId = P_CLIENT_END + (enFightAttrModule_AddPoint - 1)*C_FIGHT_ATTR_END + vecCfg[i].Type;  
			if (baseAttrId == 0 || baseAttrValue == 0)
				continue;
			attrmap[baseAttrId] = baseAttrValue;
		}
	}
}

void AttrMgr::InitPlayerSynAttr()
{
	//注册玩家广播属性
	m_PAttrBroadCast[P_HP] = 1;
	m_PAttrBroadCast[P_MAX_HP] = 1;
	m_PAttrBroadCast[P_LEVEL] = 1;
	m_PAttrBroadCast[P_MSPEED] = 1;
	m_PAttrBroadCast[P_TEAM_ID] = 1;
	m_PAttrBroadCast[P_TEAM_LEADER_ID] = 1;
	m_PAttrBroadCast[P_USE_TITLE] = 1;
	m_PAttrBroadCast[P_ADDATTR_TITLE] = 1;
	m_PAttrBroadCast[P_CAMP_ID] = 1;
	m_PAttrBroadCast[P_UNION_ID] = 1;
	m_PAttrBroadCast[P_SONOFKILLING_TIME] = 1;
	m_PAttrBroadCast[P_CURSE_OF_FALL] = 1;
}

void AttrMgr::InitPlayerAttr()
{
	memset(m_CAttrToPAttr, P_NONE, C_MAX);
	memset(m_PAttrBroadCast, 0, P_MAX);
	//与公共属性映射
	InitPlayerBaseAttr();	  //基础
	InitPlayerAdvanceAttr();  //高级属性
	InitAdvCfgIdTransToPAttr();  //高级属性
	InitPlayerSynAttr();//广播

	HandlePAddFormula(); //全部信息注册完毕后处理
}

void AttrMgr::InitMonsterAttr()
{
	memset(m_CAttrToMAttr, M_NONE, M_MAX);
	memset(m_MAttrBroadCast, 0, M_MAX);

	InitMonsterBaseAttr();
	InitMonsterSynAttr();

	HandleMAddFormula();
}

void AttrMgr::InitMonsterBaseAttr()
{
	m_CAttrToMAttr[C_LEVEL] = M_LEVEL;
	for (int i = C_POWER; i < C_FIGHT_ATTR_END; ++i)
	{
		m_CAttrToMAttr[i] = M_ATTR_ULONG_END + i;
		if (i == C_HP)
		{
			m_CAttrToMAttr[i] = M_HP;
		}
		else if (i==C_MAX_HP)
		{
			m_CAttrToMAttr[i] = M_MAX_HP;
		}
	}

	for (int m = enFightAttrModuleMonster_Level; m < enFightAttrModuleMonster_Max; ++m)
	{
		for (int i = C_POWER; i < C_FIGHT_ATTR_END; ++i)
		{
			m_CAttrToMAttr[M_USE_ATTR_END + (m - 1)*C_FIGHT_ATTR_END + i] = M_USE_ATTR_END + (m - 1)*C_FIGHT_ATTR_END + i;
		}

		for (int i = C_POWER; i < C_FIGHT_ATTR_END; ++i)
		{
			RegisterMAFormula(i + M_ATTR_ULONG_END, M_USE_ATTR_END + (m - 1)*C_FIGHT_ATTR_END + i);
		}
	}
}

void AttrMgr::InitMonsterSynAttr()
{
	////注册怪物广播属性
	m_MAttrBroadCast[M_HP] = 1;
	m_MAttrBroadCast[M_MSPEED] = 1;
	m_MAttrBroadCast[M_LAST_USE_MONSTER_TIME] = 1;
}



//怪物只有几个用于计算属性的模块，和人物有些不一样，所以这里加个这个上限判断
uint32_t AttrMgr::GetMAttr(uint32_t CAttrNum)
{
	if (CAttrNum <= C_NONE || CAttrNum >= C_MAX || CAttrNum >= M_MAX)
		return M_NONE;

	return m_CAttrToMAttr[CAttrNum];
}


uint32_t AttrMgr::GetPAttr(uint32_t CAttrNum)
{
	if (CAttrNum <= C_NONE || CAttrNum >= C_MAX)
		return P_NONE;

	return m_CAttrToPAttr[CAttrNum];
}

uint32_t AttrMgr::GetCAttrNum(uint32_t PAttrNum)
{
	if (PAttrNum<=P_NONE || PAttrNum >=P_MAX)
	{
		return C_NONE;
	}
	for (int i = C_NONE; i < (int)C_MAX;++i)
	{
		if (m_CAttrToPAttr[i] == PAttrNum )
		{
			return i;
		}
	}
	return C_NONE;
}


uint32_t AttrMgr::GetPlayerFightModlePAttr(enFightAttrModule modleID, uint32_t CAttrNum)
{
	if (CAttrNum <= C_NONE || CAttrNum >= C_MAX)
		return P_NONE;
	return P_CLIENT_END + (modleID - 1)*C_FIGHT_ATTR_END + CAttrNum; 
}


AttrMgr::VecAttr* AttrMgr::GetPAddAtrrsFormula(uint32_t PAttrNum)
{
	AttrVecMap::iterator iter = m_mapPlayerAddFormula.find(PAttrNum);
	if (iter == m_mapPlayerAddFormula.end())
		return nullptr;

	return &(iter->second);
}

AttrMgr::VecAttr* AttrMgr::GetPAddAtrrsFormulaHasPer(uint32_t PAttrNum)
{
	AttrVecMap::iterator iter = m_mapPlayerAddFormulaHasPercent.find(PAttrNum);
	if (iter == m_mapPlayerAddFormulaHasPercent.end())
		return nullptr;

	return &(iter->second);
}

AttrMgr::VecAttr* AttrMgr::GetMAddAtrrsFormulaHasPer(uint32_t MAttrNum)
{
	AttrVecMap::iterator iter = m_mapMonsterAddFormulHasPercent.find(MAttrNum);
	if (iter == m_mapMonsterAddFormulHasPercent.end())
		return nullptr;

	return &(iter->second);
}

AttrMgr::VecAttr* AttrMgr::GetMAddAttrsFormula(uint32_t PAttrNum)
{
	AttrVecMap::iterator iter = m_mapMonsterAddFormula.find(PAttrNum);
	if (iter == m_mapMonsterAddFormula.end())
		return nullptr;

	return &(iter->second);
}

AttrMgr::VecAttr* AttrMgr::GetPAFinalFormula(uint32_t PAttrNum)
{
	AttrVecMap::iterator iter = m_mapPAFinalFormula.find(PAttrNum);
	if (iter == m_mapPAFinalFormula.end())
		return nullptr;
	return &(iter->second);
}

AttrMgr::mapAttr* AttrMgr::GetAdvanceAttrsAgrs(uint32_t playerProf, uint32_t PAttrNum)
{
	profAdvAttrMap::iterator profIter = m_mapTransAttrs.find(playerProf);
	if (profIter == m_mapTransAttrs.end())
		return nullptr;
	AdvAttrMap::iterator iter = profIter->second.find(PAttrNum);
	if (iter == profIter->second.end())
		return nullptr;
	return &(iter->second);
}
//某个职业的，记录能改变该属性的属性集合
void  AttrMgr::GetAdvanceAttrsBeAdd(uint32_t playerProf, uint32_t PAttrNum, AttrMgr::mapAttr & tmpVecAttr)
{
	profAdvAttrMap::iterator profIter = m_mapTransAttrs.find(playerProf);
	if (profIter == m_mapTransAttrs.end())
		return ;
	AdvAttrMap::iterator iter = profIter->second.begin();
	for (; iter != profIter->second.end();++iter)
	{
		mapAttr::iterator iterMap = iter->second.find(PAttrNum);
		if (iterMap != iter->second.end())
		{
			tmpVecAttr[iter->first] = iterMap->second;
		}
	}
	return;
}

bool  AttrMgr::IsBroadcastPAttr(uint32_t PAttr) const 
{ 
	if (PAttr >= P_MAX)
	{
		return false;
	}
	return m_PAttrBroadCast[PAttr] > 0 ? true : false; 
}

bool AttrMgr::IsBroadcastMAttr(uint32_t MAttr) const
{
	if (MAttr >= M_MAX)
	{
		return false;
	}
	return m_MAttrBroadCast[MAttr] > 0 ? true : false;
}

AttrMgr::VecAttr* AttrMgr::GetMAFinalFormula(uint32_t MAttrNum)
{
	AttrVecMap::iterator iter = m_mapMAFinalFormula.find(MAttrNum);
	if (iter == m_mapMAFinalFormula.end())
		return nullptr;
	return &(iter->second);
}

uint32_t AttrMgr::GetTitlePNumStartIndex()
{
	return P_CLIENT_END + (enFightAttrModule_Title - 1)*C_FIGHT_ATTR_END+1;
}
uint32_t AttrMgr::GetTitlePNumEndIndex()
{
	return P_CLIENT_END + enFightAttrModule_Title*C_FIGHT_ATTR_END;
}

uint32_t AttrMgr::GetEquipPNumStartIndex()
{
	return P_CLIENT_END + (enFightAttrModule_Equip - 1)*C_FIGHT_ATTR_END;
}
uint32_t AttrMgr::GetEquipPnumEndIndex()
{
	return P_CLIENT_END + enFightAttrModule_Equip*C_FIGHT_ATTR_END;
}

//获取buff对应的c属性
uint32_t AttrMgr::GetBuffCNumAttr(uint8_t creatureType, uint32_t CAttrNum)
{
	if (creatureType == CREATURE_PLAYER)
	{
		return P_CLIENT_END + (enFightAttrModule_Buff - 1)*C_FIGHT_ATTR_END + CAttrNum;
	}
	else
	{
		return M_USE_ATTR_END + (enFightAttrModule_Buff - 1)*C_FIGHT_ATTR_END + CAttrNum;
	}
	
}

uint32_t AttrMgr::GetSKillCNumAttr(uint8_t creatureType, uint32_t CAttrNum)
{
	if (creatureType == CREATURE_PLAYER)
	{
		return P_CLIENT_END + (enFightAttrModule_Skill - 1)*C_FIGHT_ATTR_END + CAttrNum;
	}
	else
	{
		return M_USE_ATTR_END + (enFightAttrModule_Skill - 1)*C_FIGHT_ATTR_END + CAttrNum;
	}
}

uint32_t AttrMgr::GetLevCNumAttr(uint8_t creatureType, uint32_t CAttrNum)
{
	if (creatureType == CREATURE_PLAYER)
	{
		return P_CLIENT_END + (enFightAttrModule_Level - 1)*C_FIGHT_ATTR_END + CAttrNum;
	}
	else
	{
		return M_USE_ATTR_END + (enFightAttrModule_Level - 1)*C_FIGHT_ATTR_END + CAttrNum;
	}
}

uint32_t AttrMgr::GetMonsterLevMNumAttr(uint32_t CAttrNum)
{
	if (CAttrNum>C_FIGHT_ATTR_END)
	{
		return m_CAttrToMAttr[CAttrNum];
	}
	else
	{
		return M_USE_ATTR_END + (enFightAttrModule_Level - 1)*C_FIGHT_ATTR_END + CAttrNum;
	}
	
}

bool AttrMgr::IsCanNegativeMAttr(uint32_t MAttr)
{
	if (MAttr == M_SPEED_PERCENT || MAttr == M_MAXHPRATE
		|| MAttr == M_MAXMPRATE || MAttr == M_APRATE
		|| MAttr == M_MATRATE || MAttr == M_DPRATE
		|| MAttr == M_MDPRATE)
	{
		return true;
	}

	return false;
}

void AttrMgr::InitCurrencyName()
{
	m_mapCurrencyName[C_DIAMOND] = "钻石";
	m_mapCurrencyName[C_DIAMOND_BIND] = "绑定钻石";
	m_mapCurrencyName[C_GOLD] = "金币";
	m_mapCurrencyName[C_UNION_CONTRI] = "工会贡献";
	m_mapCurrencyName[C_CAMP_SCORE] = "军功";
	m_mapCurrencyName[C_ARENA_SCORE] = "声望";
} 

const char* AttrMgr::GetCurrencyName(uint32_t CAttr)
{
	CurrencyNameMap::iterator iter = m_mapCurrencyName.find(CAttr);
	if (iter != m_mapCurrencyName.end())
	{
		return iter->second.c_str();
	}
	return nullptr;
}